import sympy as sp

import math


def calculate_polar_moment_of_inertia(D, t):
    """
    计算钢管的极惯性矩

    参数:
    D (float): 钢管的外径 (单位: 米)
    t (float): 钢管的壁厚 (单位: 米)

    返回:
    float: 钢管的极惯性矩 (单位: 米^4)
    """
    I = (math.pi / 64) * (D ** 4 - (D - 2 * t) ** 4)
    return I


def calculate_outer_diameter(thickness, inertia_moment):
    """
    根据壁厚和惯性矩计算钢管的外径

    参数:
    thickness (float): 钢管的壁厚，单位：mm
    inertia_moment (float): 钢管的惯性矩，单位：mm^4

    返回:
    float: 钢管的外径，单位：mm
    """
    # 定义符号变量
    D = sp.symbols('D')

    # 内径
    d = D - 2 * thickness

    # 惯性矩公式
    equation = sp.Eq((sp.pi / 64) * (D ** 4 - d ** 4), inertia_moment)

    # 求解方程
    solutions = sp.solve(equation, D)

    # 过滤出正数解
    positive_solutions = [sol.evalf() for sol in solutions if sol.is_real and sol > 0]

    if positive_solutions:
        return positive_solutions[0]
    else:
        raise ValueError("未找到有效的外径解")


# 将小数近似转换为分母为整数且分子为1的分数
def decimal_to_unit_fraction(decimal):
    """
    将小数近似转换为分母为整数且分子为1的分数
    :param decimal: float, 小数
    :return: str, 单位分数字符串
    """
    if decimal <= 0 or decimal >= 1:
        raise ValueError("输入的小数必须在0到1之间")

    # 初始化最小误差和最佳分母
    min_error = float('inf')
    best_denominator = 1

    # 遍历可能的分母值，直到找到误差最小的
    for denominator in range(1, 10000):  # 可以根据需要调整范围
        error = abs(decimal - 1 / denominator)
        if error < min_error:
            min_error = error
            best_denominator = denominator
        if min_error == 0:
            break  # 如果找到了完全匹配的分数，则提前结束循环

    return f"1/{best_denominator}"


def test_calculate_outer_diameter():
    # 示例调用
    thickness = 4  # 壁厚，单位：mm
    inertia_moment = 1925.51944003617  # 惯性矩，单位：mm^4

    outer_diameter = calculate_outer_diameter(thickness, inertia_moment)
    print(f"钢管的外径 D (mm): {outer_diameter}")
    outer_diameter = int(outer_diameter)
    print(f"外径取值：{outer_diameter},再计算钢管的极惯性矩 I (mm^4):{calculate_polar_moment_of_inertia(outer_diameter, thickness)}")


def test_decimal_to_unit_fraction():
    print(decimal_to_unit_fraction(0.5))


if __name__ == "__main__":
    pass
    test_calculate_outer_diameter()
    # test_decimal_to_unit_fraction()
